﻿using JNPF.Logging;
using Nancy.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace PARK.Common.WeChat
{
    public class WechatUser
    {
        /// <summary>
        /// openid用于调用统一下单接口
        /// </summary>
        public string Openid { get; set; }
        /// <summary>
        /// 当前用户昵称
        /// </summary>
        public string Nickname { get; set; }
        /// <summary>
        /// 用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
        /// </summary>
        public string Sex { get; set; }
        /// <summary>
        /// 用户所在省份
        /// </summary>
        public string Province { get; set; }
        /// <summary>
        /// 用户所在城市
        /// </summary>
        public string City { get; set; }

        /// <summary>
        /// 用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），用户没有头像时该项为空
        /// </summary>
        public string HeadImgUrl { get; set; }

        /// <summary>
        /// openid用于调用统一下单接口
        /// </summary>
        public string phoneNumber { get; set; }
        /// <summary>
        /// access_token用于获取收货地址js函数入口参数
        /// </summary>
        public string access_token { get; set; }

        /**
	    * 
	    * 通过code换取网页授权access_token和openid的返回数据，正确时返回的JSON数据包如下：
	    * {
	    *  "access_token":"ACCESS_TOKEN",
	    *  "expires_in":7200,
	    *  "refresh_token":"REFRESH_TOKEN",
	    *  "openid":"OPENID",
	    *  "scope":"SCOPE",
	    *  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
	    * }
	    * 其中access_token可用于获取共享收货地址
	    * openid是微信支付jsapi支付接口统一下单时必须的参数
        * 更详细的说明请参考网页授权获取用户基本信息
        * @失败时抛异常WxPayException
	    */
        public int GetOpenidAndAccessTokenFromCode(string code, string APPID, string APPSECRET)
        {
            setlog("code:" + code + ";APPID:" + APPID + ";APPSECRET:" + APPSECRET);
            int _ret = 0;
            try
            {
                //构造获取openid及access_token的url
                WxPayData data = new WxPayData();
                data.SetValue("appid", APPID);
                data.SetValue("secret", APPSECRET);
                data.SetValue("js_code", code);
                data.SetValue("grant_type", "authorization_code");
                //string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + data.ToUrl();
                string url = "https://api.weixin.qq.com/sns/jscode2session?" + data.ToUrl();
                //请求url以获取数据
                string result = Getresult(url);
                setlog(result);
                if (!string.IsNullOrEmpty(result))
                {
                    JObject jd = (JObject)JsonConvert.DeserializeObject(result.ToString());
                    //获取用户openid
                    Openid = (string)jd["openid"];
                    _ret = 1;
                }
            }
            catch
            {
            }
            return _ret;
        }
        /// <summary>
        /// 获取token
        /// </summary>
        /// <param name="APPID"></param>
        /// <param name="APPSECRET"></param>
        /// <returns></returns>
        public int GetAccessToken(string APPID, string APPSECRET)
        {
            setlog("GetAccessToken->APPID:" + APPID + ";APPSECRET:" + APPSECRET);
            int _ret = 0;
            try
            {
                WxPayData data = new WxPayData();
                data.SetValue("appid", APPID);
                data.SetValue("secret", APPSECRET);
                data.SetValue("grant_type", "client_credential");
                string url = "https://api.weixin.qq.com/cgi-bin/token?" + data.ToUrl();
                //请求url以获取数据
                string result = Getresult(url);
                setlog("GetAccessToken->微信接口返回:" + result);
                if (!string.IsNullOrEmpty(result))
                {
                    JObject jd = (JObject)JsonConvert.DeserializeObject(result.ToString());
                    access_token = (string)jd["access_token"];
                    _ret = 1;
                }
            }
            catch
            {
            }
            return _ret;
        }
        /// <summary>
        /// 通过code换取用户手机号码
        /// </summary>
        /// <param name="code"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        public int GetPhoneNumberFromCode(string code, string accesstoken)
        {
            setlog("通过code换取用户手机号码->code:" + code + ";accesstoken:" + accesstoken);
            int _ret = 0;
            try
            {
                var sb = new StringBuilder("");
                sb.Append("{\"code\":\"" + code + "\"}");
                HttpClient client = new HttpClient();
                var bodyJson = new StringContent(sb.ToString(), Encoding.UTF8, "application/json");
                var resp = client.PostAsync("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accesstoken, bodyJson).Result;
                var result = resp.Content.ReadAsStringAsync().Result;
                setlog("通过code换取用户手机号码->" + result);
                if (!string.IsNullOrEmpty(result))
                {
                    JObject jd = (JObject)JsonConvert.DeserializeObject(result.ToString());
                    if (jd != null)
                    {
                        JObject _phone = (JObject)JsonConvert.DeserializeObject(jd["phone_info"].ToString());
                        if (_phone != null)
                        {
                            phoneNumber = (string)_phone["phoneNumber"];
                            _ret = 1;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                new LoggEx().errlog("GetPhoneNumberFromCode()->" + ex.Message);
            }
            return _ret;
        }
        static void setlog(string str)
        {
            string name = DateTime.Now.ToString("yyyy-MM-dd") + ".log";
            string rootPath = Directory.GetCurrentDirectory();
            string path = $@"{rootPath}/logs/Wechat";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            using (FileStream fs = new FileStream(path + "/" + name, FileMode.Append))
            {
                str = "\r\n日期：" + DateTime.Now.ToString() + "\r\n消息：" + str;
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine(str);
                sw.Flush();
                sw.Close();
            }
        }
        string Getresult(string url)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "textml;charset=UTF-8";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
            string jsonData = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            return jsonData;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="accessToken"></param>
        /// <param name="openId"></param>
        /// <returns></returns>
        public WeChatUserEntity GetUserIfo(string accessToken, string openId)
        {
            WeChatUserEntity wue = new WeChatUserEntity();
            string url = "https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN";
            url = string.Format(url, accessToken, openId);
            try
            {

                WebClient wc = new WebClient();
                byte[] pageData = wc.DownloadData(url);
                string jsonStr = Encoding.UTF8.GetString(pageData);
                JavaScriptSerializer jss = new JavaScriptSerializer();
                wue = jss.Deserialize<WeChatUserEntity>(jsonStr);
            }
            catch (WebException ex)
            {
                throw ex;
            }
            return wue;
        }

        /// <summary>
        /// 通过appID和appsecret获取Access_token
        /// </summary>
        /// <returns></returns>
        public static Access_tokenModel GetAccess_token(string appid, string secret, out string ret)
        {
            new LoggEx().Info("准备开始获取Access_tokenModel(2)....");
            Access_tokenModel mode = new Access_tokenModel();
            string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
            try
            {

                WebClient wc = new WebClient();
                byte[] pageData = wc.DownloadData(url);
                string jsonStr = Encoding.UTF8.GetString(pageData);
                setlog(jsonStr);
                ret = jsonStr;
                Access_tokenModel token = new Access_tokenModel();
                JavaScriptSerializer javazer = new JavaScriptSerializer();
                Access_tokenModel list = javazer.Deserialize<Access_tokenModel>(jsonStr);
                mode.access_token = list.access_token;
                mode.expires_in = list.expires_in;
            }
            catch (WebException ex)
            {
                ret = ex.Message;
                new LoggEx().Info("获取Access_token,遇到异常:" + ex.Message);
            }
            return mode;
        }
    }
}
